/*
 * $Id: list.h,v 1.4 2006-02-07 07:23:30 bacon Exp $
 */

#ifndef _XP_BAS_LIST_H_
#define _XP_BAS_LIST_H_

#include <xp/types.h>
#include <xp/macros.h>

typedef struct xp_list_t xp_list_t;
typedef struct xp_list_callback_t xp_list_callback_t;
typedef struct xp_list_link_t xp_list_link_t;
typedef struct xp_list_chunk_t xp_list_chunk_t;

/* TODO: refer to arr.h for imporved callbacks */
struct xp_list_callback_t
{
	void (*initialize) (xp_list_t* list);
	/*void (*adjust) (xp_list_t* list);*/
	void (*finalize) (xp_list_t* list);
};

struct xp_list_link_t
{
	xp_list_link_t* prev;
	xp_list_link_t* next;
	/*xp_byte_t byte[1];*/
};

struct xp_list_chunk_t
{
	xp_list_chunk_t* next;
	/*xp_byte_t byte[1];*/
};

struct xp_list_t
{
	xp_size_t chunk_size; /* chunk size in the number of datum. 
	                       * i.e. chunk size in bytes = chunk_size * datum_size
	                       */
	xp_size_t datum_size; /* datum size in bytes */
	xp_size_t size;       /* number of datum */
	xp_size_t capacity;   /* maximum number of datum */

	xp_list_chunk_t* chunk;
	xp_list_link_t* head;
	xp_list_link_t* tail;
	xp_list_link_t* free;

	xp_list_callback_t* callback;
	xp_bool_t __dynamic;
};


#ifdef __cplusplus
extern "C" {
#endif

xp_list_t* xp_list_open (
	xp_list_t* list, xp_size_t capacity,
	xp_size_t datum_size, xp_list_callback_t* callback);
void xp_list_close (xp_list_t* list);

void* xp_list_append (xp_list_t* list, const void* value);

xp_size_t xp_list_walk (
	xp_list_t* list, xp_ssize_t (*func) (xp_list_t*, void*));


#ifdef __cplusplus
}
#endif

#endif
